﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace UIBParser
{
    public partial class MainForm : Form
    {
        private BindingList<GridViewEntry> list = new BindingList<GridViewEntry>();
        string currentFilename = "";
        public MainForm()
        {
            InitializeComponent();
            UpdateTitle();
        }
        void UpdateTitle()
        {
            if (string.IsNullOrEmpty(currentFilename))
                this.Text = "Dune 2000 String Table Editor";
            else
                this.Text = currentFilename + " - " + "Dune 2000 String Table Editor";
        }

        private void ParseUIB(string filename)
        {
            currentFilename = Path.GetFileNameWithoutExtension(filename);
            UpdateTitle();
            //Load the file
            FileStream fs = File.OpenRead(filename);
            BinaryReader br = new BinaryReader(fs);

            //Console.Write(br.ReadUInt32().ToString());
            UInt32 entryCount = br.ReadUInt32();

            int length;

             list = new BindingList<GridViewEntry>();
            char[] stringCharArray;
            List<char> stringCharList;

            List<string> tempList = new List<string>();

            for (int i = 0; i < entryCount; i++)
            {
                length = br.ReadUInt16();

                stringCharArray = new char[length];
                for (int j = 0; j < length; j++)
                {
                    stringCharArray[j] = br.ReadChar();
                }
                stringCharList = stringCharArray.ToList<char>();
                stringCharList.RemoveAt(stringCharList.Count - 1);
                string hashMapKey = new string(stringCharList.ToArray());
                //br.ReadByte();
                length = br.ReadUInt16();

                stringCharArray = new char[length];
                for (int j = 0; j < length; j++)
                {
                    stringCharArray[j] = (char)br.ReadByte();
                }
                stringCharList = stringCharArray.ToList<char>();
                //stringCharList.RemoveAt(stringCharList.Count - 2);
                stringCharList.RemoveAt(stringCharList.Count - 1);
                string hashMapValue = new string(stringCharList.ToArray());

                if (!tempList.Contains(hashMapValue))
                    tempList.Add(hashMapValue);
                //br.ReadByte();
                //br.ReadBytes(8);
                
                list.Add(new GridViewEntry(hashMapKey, hashMapValue));                
            }            
                
            br.Close();
            fs.Close();

            Console.WriteLine(tempList.Count.ToString() + " Unique Values Found.");

            dataGridView1.DataSource = list;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            if (dataGridView1.Columns.Count == 2)
            {
                dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }
            
        }

        private void SaveUIB(string filename)
        {
            //Load the file
            FileStream fs = File.Create(filename);
            BinaryWriter bw = new BinaryWriter(fs);

            UInt32 entryCount = Convert.ToUInt32(dataGridView1.Rows.Count);
            bw.Write(entryCount);

            UInt16 length;
            //List<TestObject> list = new List<TestObject>();
            //char[] stringCharArray;
            //List<char> stringCharList;

            //List<string> tempList = new List<string>();

            for (int i = 0; i < entryCount; i++)
            {
                string hashMapKey = list[i].Key;
                length = Convert.ToUInt16(hashMapKey.Length);
                length++;
                bw.Write(length);
                for (int j = 0; j < hashMapKey.Length; j++)
                {
                    bw.Write((byte)hashMapKey[j]);
                }
                bw.Write('\0'); // Append null terminator

                string hashMapValue = list[i].Value;
                length = Convert.ToUInt16(hashMapValue.Length);
                length++;
                bw.Write(length);
                for (int j = 0; j < hashMapValue.Length; j++)
                {
                    bw.Write((byte)hashMapValue[j]);
                }
                bw.Write('\0'); // Append null terminator
            }

            bw.Close();
            fs.Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
        }
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("www.mvinetwork.co.uk/dune"); 
        }

        private void openButton_Click(object sender, EventArgs e)
        {
            //Let the user pick the files to parse
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Dune 2000 UIB files (*.uib)|*.uib";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                ParseUIB(dlg.FileName);
            }
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            //Let the user pick the files to parse
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.FileName = currentFilename;
            dlg.Filter = "Dune 2000 UIB files (*.uib)|*.uib";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                SaveUIB(dlg.FileName);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count == 1)
            {
                //if(dataGridView1.SelectedRows[0] != -1)
                list.RemoveAt(dataGridView1.SelectedRows[0].Index);
            }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count == 1)
            {
                list.Insert(dataGridView1.SelectedRows[0].Index, new GridViewEntry("", ""));
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count == 1)
            {
                list.Insert(dataGridView1.SelectedRows[0].Index+1, new GridViewEntry("", ""));
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (dataGridView1.Rows.Count == 0)
            {
                return;
            }
            InputBoxValidation validation = delegate(string val)
            {
                int index;
                if (val == "")
                    return "Row index cannot be empty.";
                if (!int.TryParse(val, out index))
                    return "Row index must be a number.";
                if (index < 0)
                    return "Row index must be 0 or bigger";
                if (index >= dataGridView1.Rows.Count)
                    return "Row index cannot be greater than the number of rows";
                return "";
            };

            string value = "0";
            if (InputBox.Show("Row index to jump to", "Row index to jump to:", ref value, validation) == DialogResult.OK)
            {
                int index;
                int.TryParse(value, out index);
                dataGridView1.Rows[index].Selected = true;
                dataGridView1.CurrentCell = dataGridView1.Rows[index].Cells[0];
                dataGridView1.Focus();
            }
        }

    }
}
